package com.hxx.common.core.wcontour.util;

import com.hxx.common.core.wcontour.constant.FeatureAttrConstant;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.MultiPolygon;
import org.opengis.feature.Feature;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Feature裁切工具类
 *
 * @author hxd
 */
public class FeatureClipUtil {

    private static final String typeSpec = "the_geom:MultiPolygon:srid=4326,value:double";
    private static final String typeName = "MultiPolygons";


    /**
     * 根据裁切模版shapefile裁切
     *
     * @param fc        需要裁切FeatureCollection
     * @param shapefile 裁切模版shapefile
     * @return
     */
    public static FeatureCollection clipFeatureCollection(FeatureCollection fc, String shapefile) throws SchemaException {
        SimpleFeatureCollection shpFc = FeatureUtil.shpToFeatureCollection(shapefile);
        return clipFeatureCollection(shpFc, (SimpleFeatureCollection) fc);

    }

    /**
     * 结果裁切
     *
     * @param fc 裁切模版Feature
     * @param gs 被裁切对象
     * @return
     */
    public static FeatureCollection clipFeatureCollection(FeatureCollection fc, SimpleFeatureCollection gs) throws SchemaException {
        FeatureCollection cs = null;
        List<Map<String, Object>> values = new ArrayList<>();
        FeatureIterator dataFeatureIterator = fc.features();
        while (dataFeatureIterator.hasNext()) {
            Feature dataFeature = dataFeatureIterator.next();
            Object dataGeometry = dataFeature.getProperty(FeatureAttrConstant.THE_GEOM).getValue();
            // 需要每次重新获取
            FeatureIterator contourFeatureIterator = gs.features();
            if (dataGeometry instanceof MultiPolygon) {
                MultiPolygon p = (MultiPolygon) dataGeometry;
                while (contourFeatureIterator.hasNext()) {
                    Feature contourFeature = contourFeatureIterator.next();
                    Geometry contourGeometry = (Geometry) contourFeature
                            .getProperty(FeatureAttrConstant.THE_GEOM).getValue();
                    double v = (Double) contourFeature.getProperty(FeatureAttrConstant.VALUE)
                            .getValue();
                    // 是否有效
                    boolean valid = contourGeometry.isValid();
                    if (!valid) {
                        // Geometry无效时，distance：1米缓冲区，quadrantSegments用于近似四分之一圆的段数（默认为8）
                        contourGeometry = contourGeometry.buffer(1, 8);
                    }
                    if (p.intersects(contourGeometry)) {
                        Geometry geo = p.intersection(contourGeometry);
                        Map<String, Object> map = new HashMap<>(2);
                        map.put(FeatureAttrConstant.THE_GEOM, geo);
                        map.put(FeatureAttrConstant.VALUE, v);
                        values.add(map);
                    }
                }
            } else {
                Geometry p = (Geometry) dataGeometry;
                while (contourFeatureIterator.hasNext()) {
                    Feature contourFeature = contourFeatureIterator.next();
                    Geometry contourGeometry = (Geometry) contourFeature
                            .getProperty(FeatureAttrConstant.THE_GEOM).getValue();
                    double v = (Double) contourFeature.getProperty(FeatureAttrConstant.VALUE)
                            .getValue();
                    if (!contourGeometry.isValid()) {
                        // Geometry无效时，distance：1米缓冲区，quadrantSegments用于近似四分之一圆的段数（默认为8）
                        contourGeometry = contourGeometry.buffer(1, 8);
                    }
                    if (p.intersects(contourGeometry)) {
                        Geometry geo = p.intersection(contourGeometry);
                        Map<String, Object> map = new HashMap<>(2);
                        map.put(FeatureAttrConstant.THE_GEOM, geo);
                        map.put(FeatureAttrConstant.VALUE, v);
                        values.add(map);
                    }
                }
            }
            contourFeatureIterator.close();
        }
        dataFeatureIterator.close();
        return creatFeatureCollection(values);
    }

    /**
     * geotools创建FeatureCollection
     *
     * @param values
     * @return
     * @throws SchemaException
     */
    public static FeatureCollection creatFeatureCollection(List<Map<String, Object>> values) throws SchemaException {
        SimpleFeatureType type = DataUtilities.createType(typeName, typeSpec);
        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
        DefaultFeatureCollection collection = new DefaultFeatureCollection();
        for (Map feat : values) {
            featureBuilder.reset();
            featureBuilder.add(feat.get(FeatureAttrConstant.THE_GEOM));
            featureBuilder.add(feat.get(FeatureAttrConstant.VALUE));
            SimpleFeature feature = featureBuilder.buildFeature(null);
            collection.add(feature);
        }
        return collection;
    }


}
